package com.log4jviewer.ui.preferences.filters;

import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.widgets.Text;

import com.log4jviewer.filters.FilterConstants;
import com.log4jviewer.filters.FilterItemModel;

/**
 * Create possibility modify the Match cell in Rules Table
 * 
 * @author <a href="mailto:solid.danil@gmail.com">Daniil Lopatin</a>
 */
public class RulesMatchPatternCellEditor extends EditingSupport {

    private final TableViewer tableViewer;

    public RulesMatchPatternCellEditor(final TableViewer tableViewer) {
        super(tableViewer);
        this.tableViewer = tableViewer;
    }

    @Override
    protected CellEditor getCellEditor(final Object element) {
        FilterItemModel filterItemModel = (FilterItemModel) element;
        CellEditor cellEditor = null;

        // Add Levels ComboBox for Level type
        if ((FilterConstants.LEVEL).equals(filterItemModel.getFieldType())) {
            cellEditor = new ComboBoxCellEditor(tableViewer.getTable(), FilterConstants.LOG_LEVELS,
                    SWT.READ_ONLY);
        } else {
            cellEditor = new TextCellEditor(tableViewer.getTable());

            // If need to enter Line number (Text with digits only)
            if ((FilterConstants.LINE).equals(filterItemModel.getFieldType())) {
                ((Text) cellEditor.getControl()).addVerifyListener(new VerifyListener() {
                    @Override
                    public void verifyText(final VerifyEvent e) {
                        // Here, we could use a RegExp such as the following
                        // if using JRE1.4 such as e.doit = e.text.matches("[\\-0-9]*");
                        // another way to check:
                        // e.doit = "0123456789".indexOf(e.text) >= 0;
                        e.doit = e.text.matches("[\\d]*");
                    }
                });
            }
        }
        return cellEditor;
    }

    @Override
    protected boolean canEdit(final Object element) {
        return true;
    }

    @Override
    protected Object getValue(final Object element) {
        FilterItemModel filterItemModel = (FilterItemModel) element;
        Object matchPattern = filterItemModel.getPattern();

        if (FilterConstants.LEVEL.equals(filterItemModel.getFieldType())) {
            matchPattern = 0;
        }
        // If used Free Text
        return matchPattern;
    }

    @Override
    protected void setValue(final Object element, final Object value) {
        FilterItemModel filterItemModel = (FilterItemModel) element;

        if (value instanceof Number) {
            // If ComboBox levels
            filterItemModel.setPattern(FilterConstants.LOG_LEVELS[(Integer) value]);
        } else {
            String matchPattern = String.valueOf(value);
            // If empty number line (Line type)
            if ((matchPattern.length() == 0) && FilterConstants.LINE.equals(filterItemModel.getFieldType())) {
                matchPattern = "0";
            }
            // If free text
            filterItemModel.setPattern(matchPattern);
        }
        tableViewer.update(element, null);
    }
}
